package site.lanmushan.validation.validator;


import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import site.lanmushan.validation.annotation.PasswordPatten;

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;


/**
 * @author Administrator
 */
public class PasswordPattenValidator implements ConstraintValidator<PasswordPatten, String> {
    private String defaultMsg;
    private Integer minLength;
    private Integer maxLength;

    @Override
    public void initialize(PasswordPatten annotation) {
        this.minLength = annotation.minLength();
        this.maxLength = annotation.maxLength();
        this.defaultMsg = annotation.message();
    }

    @Override
    public boolean isValid(String value, ConstraintValidatorContext constraintValidatorContext) {
        if (ObjectUtil.isEmpty(value)) {
            return true;
        }
        if (!validatePassword(value)) {
            if (ObjectUtil.isEmpty(defaultMsg)) {
                constraintValidatorContext.disableDefaultConstraintViolation();
                constraintValidatorContext.buildConstraintViolationWithTemplate("密码格式错误大写字母，小写字母，特殊字符").addConstraintViolation();
            }
            return false;
        }
        if (value.length() < minLength || value.length() > maxLength) {
            if (ObjectUtil.isEmpty(defaultMsg)) {
                constraintValidatorContext.disableDefaultConstraintViolation();
                constraintValidatorContext.buildConstraintViolationWithTemplate(String.format("密码长度必须为%s至%s位", minLength, maxLength))
                        .addConstraintViolation();
            }
            return false;
        }
        return true;
    }

    /**
     * 校验方法，校验规则
     *
     * @param password 值
     * @return 是否符合规则，true通过，false不通过
     */
    private boolean validatePassword(String password) {
        return StrUtil.containsAny(password, "-_+=,.?~!@#$%^&*()")
                && StrUtil.containsAny(password, "abcdefghijklmnopqrstuvwxyz")
                && StrUtil.containsAny(password, "ABCDEFGHIJKLMNOPQRSTUVWXYZ")
                && StrUtil.containsAny(password, "0123456789");
    }
}
